home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / Devcon_Extras / Example_Code / SampleLibrary / library / sample.library.asm next >
Encoding:
Assembly Source File  |  1992-08-27  |  10.0 KB  |  352 lines

  1. *************************************************************************
  2. *                                                                       *
  3. *   sample.library.asm -- Example run-time library source code          *
  4. *                                                                       *
  5. *   Copyright (C) 1985, 1988 Commodore Amiga Inc.  All rights reserved. *
  6. *                                                                       *
  7. *   Assemble and link, without startup code, to create Sample.library,  *
  8. *     a LIBS: drawer run-time shared library                            *
  9. *                                                                       *
  10. *  Linkage Info:                                                        *
  11. *  FROM     sample.library.o                                            *
  12. *  LIBRARY  LIB:Amiga.lib                                               *
  13. *  TO       sample.library                                              *
  14. *                                                                       *
  15. *************************************************************************
  16.  
  17.    SECTION   section
  18.  
  19.    NOLIST
  20.    INCLUDE "exec/types.i"
  21.    INCLUDE "exec/libraries.i"
  22.    INCLUDE "exec/lists.i"
  23.    INCLUDE "exec/alerts.i"
  24.    INCLUDE "exec/initializers.i"
  25.    INCLUDE "exec/resident.i"
  26.    INCLUDE "libraries/dos.i"
  27.  
  28.    INCLUDE "asmsupp.i"
  29.    INCLUDE "samplebase.i"
  30.  
  31.    LIST
  32.  
  33.    ;------ These don't have to be external, but it helps some
  34.    ;------ debuggers to have them globally visible
  35.    XDEF   Init
  36.    XDEF   Open
  37.    XDEF   Close
  38.    XDEF   Expunge
  39.    XDEF   Null
  40.    XDEF   sampleName
  41.    XDEF   Double
  42.    XDEF   AddThese
  43.  
  44.    XREF   _AbsExecBase
  45.  
  46.    XLIB   OpenLibrary
  47.    XLIB   CloseLibrary
  48.    XLIB   Alert
  49.    XLIB   FreeMem
  50.    XLIB   Remove
  51.  
  52.  
  53.  
  54.    ; The first executable location.  This should return an error
  55.    ; in case someone tried to run you as a program (instead of
  56.    ; loading you as a library).
  57. Start:
  58.    MOVEQ   #-1,d0
  59.    rts
  60.  
  61. ;-----------------------------------------------------------------------
  62. ; A romtag structure.  Both "exec" and "ramlib" look for
  63. ; this structure to discover magic constants about you
  64. ; (such as where to start running you from...).
  65. ;-----------------------------------------------------------------------
  66.  
  67.    ; Most people will not need a priority and should leave it at zero.
  68.    ; the RT_PRI field is used for configuring the roms.  Use "mods" from
  69.    ; wack to look at the other romtags in the system
  70. MYPRI   EQU   0
  71.  
  72. initDDescrip:
  73.                ;STRUCTURE RT,0
  74.      DC.W    RTC_MATCHWORD      ; UWORD RT_MATCHWORD
  75.      DC.L    initDDescrip       ; APTR  RT_MATCHTAG
  76.      DC.L    EndCode            ; APTR  RT_ENDSKIP
  77.      DC.B    RTF_AUTOINIT       ; UBYTE RT_FLAGS
  78.      DC.B    VERSION            ; UBYTE RT_VERSION
  79.      DC.B    NT_LIBRARY         ; UBYTE RT_TYPE
  80.      DC.B    MYPRI              ; BYTE  RT_PRI
  81.      DC.L    sampleName         ; APTR  RT_NAME
  82.      DC.L    idString           ; APTR  RT_IDSTRING
  83.      DC.L    Init               ; APTR  RT_INIT
  84.  
  85.  
  86.    ; this is the name that the library will have
  87. sampleName:    SAMPLENAME
  88.  
  89.    ; a major version number.
  90. VERSION:   EQU   34
  91.  
  92.    ; A particular revision.  This should uniquely identify the bits in the
  93.    ; library.  I use a script that advances the revision number each time
  94.    ; I recompile.  That way there is never a question of which library
  95.    ; that really is.
  96. REVISION:   EQU  1
  97.  
  98.    ; this is an identifier tag to help in supporting the library
  99.    ; format is 'name version.revision (dd MON yyyy)',<cr>,<lf>,<null>
  100. idString:   dc.b   'samplelib 1.3 (03 Oct 1988)',13,10,0
  101.  
  102. dosName:   DOSNAME
  103.  
  104.    ; force word allignment
  105.    ds.w   0
  106.  
  107.  
  108.    ; The romtag specified that we were "RTF_AUTOINIT".  This means
  109.    ; that the RT_INIT structure member points to one of these
  110.    ; tables below.  If the AUTOINIT bit was not set then RT_INIT
  111.    ; would point to a routine to run.
  112.  
  113. Init:
  114.    DC.L   SampleBase_SIZEOF ; size of library base data space
  115.    DC.L   funcTable         ; pointer to function initializers
  116.    DC.L   dataTable         ; pointer to data initializers
  117.    DC.L   initRoutine       ; routine to run
  118.  
  119.  
  120. funcTable:
  121.  
  122.    ;------ standard system routines
  123.    dc.l   Open
  124.    dc.l   Close
  125.    dc.l   Expunge
  126.    dc.l   Null
  127.  
  128.    ;------ my libraries definitions
  129.    dc.l   Double
  130.    dc.l   AddThese
  131.  
  132.    ;------ function table end marker
  133.    dc.l   -1
  134.  
  135.  
  136.    ; The data table initializes static data structures.
  137.    ; The format is specified in exec/InitStruct routine's
  138.    ; manual pages.  The INITBYTE/INITWORD/INITLONG routines
  139.    ; are in the file "exec/initializers.i".  The first argument
  140.    ; is the offset from the library base for this byte/word/long.
  141.    ; The second argument is the value to put in that cell.
  142.    ; The table is null terminated
  143.    ; NOTE - LN_TYPE below is a correction - old example had LH_TYPE
  144.  
  145. dataTable:
  146.    INITBYTE   LN_TYPE,NT_LIBRARY
  147.    INITLONG   LN_NAME,sampleName
  148.    INITBYTE   LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
  149.    INITWORD   LIB_VERSION,VERSION
  150.    INITWORD   LIB_REVISION,REVISION
  151.    INITLONG   LIB_IDSTRING,idString
  152.    DC.L   0
  153.  
  154.  
  155.    ; This routine gets called after the library has been allocated.
  156.    ; The library pointer is in D0.  The segment list is in A0.
  157.    ; If it returns non-zero then the library will be linked into
  158.    ; the library list.
  159. initRoutine:
  160.  
  161.    ;------ get the library pointer into a convenient A register
  162.    move.l   a5,-(sp)
  163.    move.l   d0,a5
  164.  
  165.    ;------ save a pointer to exec
  166.    move.l   a6,sb_SysLib(a5)
  167.  
  168.    ;------ save a pointer to our loaded code
  169.    move.l   a0,sb_SegList(a5)
  170.  
  171.    ;------ open the dos library
  172.    lea   dosName(pc),a1
  173.    CLEAR   d0
  174.    CALLSYS   OpenLibrary
  175.  
  176.    move.l   d0,sb_DosLib(a5)
  177.    bne.s   1$
  178.  
  179.    ;------ can't open the dos!  what gives
  180.    ALERT   AG_OpenLib!AO_DOSLib
  181.  
  182. 1$:
  183.    ;------ now build the static data that we need
  184.  
  185.    ;
  186.    ; put your initialization here...
  187.    ;
  188.  
  189.    move.l   a5,d0
  190.    move.l   (sp)+,a5
  191.    rts
  192.  
  193. ;----------------------------------------------------------------------
  194. ;
  195. ; here begins the system interface commands.  When the user calls
  196. ; OpenLibrary/CloseLibrary/RemoveLibrary, this eventually gets translated
  197. ; into a call to the following routines (Open/Close/Expunge).  Exec
  198. ; has already put our library pointer in A6 for us.  Exec has turned
  199. ; off task switching while in these routines (via Forbid/Permit), so
  200. ; we should not take too long in them.
  201. ;
  202. ;----------------------------------------------------------------------
  203.  
  204.  
  205.    ; Open returns the library pointer in d0 if the open
  206.    ; was successful.  If the open failed then null is returned.
  207.    ; It might fail if we allocated memory on each open, or
  208.    ; if only open application could have the library open
  209.    ; at a time...
  210.  
  211. Open:      ; ( libptr:a6, version:d0 )
  212.  
  213.    ;------ mark us as having another opener
  214.    addq.w   #1,LIB_OPENCNT(a6)
  215.  
  216.    ;------ prevent delayed expunges
  217.    bclr   #LIBB_DELEXP,sb_Flags(a6)
  218.  
  219.    move.l   a6,d0
  220.    rts
  221.  
  222.    ; There are two different things that might be returned from
  223.    ; the Close routine.  If the library is no longer open and
  224.    ; there is a delayed expunge then Close should return the
  225.    ; segment list (as given to Init).  Otherwise close should
  226.    ; return NULL.
  227.  
  228. Close:      ; ( libptr:a6 )
  229.     
  230.    ;------ set the return value
  231.    CLEAR   d0
  232.  
  233.    ;------ mark us as having one fewer openers
  234.    subq.w   #1,LIB_OPENCNT(a6)
  235.  
  236.    ;------ see if there is anyone left with us open
  237.    bne.s   1$
  238.  
  239.    ;------ see if we have a delayed expunge pending
  240.    btst   #LIBB_DELEXP,sb_Flags(a6)
  241.    beq.s   1$
  242.  
  243.    ;------ do the expunge
  244.    bsr   Expunge
  245. 1$:
  246.    rts
  247.  
  248.  
  249.    ; There are two different things that might be returned from
  250.    ; the Expunge routine.  If the library is no longer open
  251.    ; then Expunge should return the segment list (as given to
  252.    ; Init).  Otherwise Expunge should set the delayed expunge
  253.    ; flag and return NULL.
  254.    ;
  255.    ; One other important note: because Expunge is called from
  256.    ; the memory allocator, it may NEVER Wait() or otherwise
  257.    ; take long time to complete.
  258.  
  259. Expunge:   ; ( libptr: a6 )
  260.  
  261.    movem.l   d2/a5/a6,-(sp)
  262.    move.l   a6,a5
  263.    move.l   sb_SysLib(a5),a6
  264.    
  265.    ;------ see if anyone has us open
  266.    tst.w   LIB_OPENCNT(a5)
  267.    beq   1$
  268.  
  269.    ;------ it is still open.  set the delayed expunge flag
  270.    bset   #LIBB_DELEXP,sb_Flags(a5)
  271.    CLEAR   d0
  272.    bra.s   Expunge_End
  273.  
  274. 1$:
  275.    ;------ go ahead and get rid of us.  Store our seglist in d2
  276.    move.l   sb_SegList(a5),d2
  277.  
  278.    ;------ unlink from library list
  279.    move.l   a5,a1
  280.    CALLSYS   Remove
  281.    
  282.    ;
  283.    ; device specific closings here...
  284.    ;
  285.  
  286.    ;------ close the dos library
  287.    move.l   sb_DosLib(a5),a1
  288.    CALLSYS   CloseLibrary
  289.  
  290.    ;------ free our memory
  291.    CLEAR   d0
  292.    move.l   a5,a1
  293.    move.w   LIB_NEGSIZE(a5),d0
  294.  
  295.    sub.l   d0,a1
  296.    add.w   LIB_POSSIZE(a5),d0
  297.  
  298.    CALLSYS   FreeMem
  299.  
  300.    ;------ set up our return value
  301.    move.l   d2,d0
  302.  
  303. Expunge_End:
  304.    movem.l   (sp)+,d2/a5/a6
  305.    rts
  306.  
  307.  
  308. Null:
  309.    CLEAR   d0
  310.    rts
  311.  
  312. ;----------------------------------------------------------------------
  313. ;
  314. ; Here begins the library specific functions.
  315. ;
  316. ; Both of these simple functions are entirely in assembler, but you
  317. ; can write your functions in C if you wish and interface to them here.
  318. ; If, for instance, the bulk of the AddThese function was written
  319. ; in C, you could interface to it as follows:
  320. ;
  321. ;   - write a C function  addTheseC(n1,n2) and compile it
  322. ;   - XDEF _addThese C  in this library code
  323. ;   - change the AddThese function code below to:
  324. ;       move.l d1,-(sp)     ;push rightmost C arg first
  325. ;       move.l d0,-(sp)     ;push other C arg(s), right to left
  326. ;       jsr    _addTheseC   ;call the C code
  327. ;       addq   #8,sp        ;fix stack
  328. ;       rts                 ;return with result in d0
  329. ;
  330. ;----------------------------------------------------------------------
  331.  
  332. *----- Double(d0)
  333. Double:
  334.    lsl     #1,d0
  335.    rts
  336.  
  337. *----- AddThese(d0,d1)
  338. AddThese:
  339.    add.l   d1,d0
  340.    rts
  341.  
  342.  
  343.    ; EndCode is a marker that show the end of your code.
  344.    ; Make sure it does not span sections nor is before the
  345.    ; rom tag in memory!  It is ok to put it right after
  346.    ; the rom tag -- that way you are always safe.  I put
  347.    ; it here because it happens to be the "right" thing
  348.    ; to do, and I know that it is safe in this case.
  349. EndCode:
  350.  
  351.    END
  352.